package com.binfenhulian.chinaenergy.ces.utils.date;
import com.binfenhulian.chinaenergy.ces.utils.random.RandomGUIDUtil;
import com.binfenhulian.chinaenergy.ces.utils.string.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.WeekFields;
import java.util.*;

public class DateUtil {
    public static String START = " 00:00:00";
    public static String END = " 23:59:59";
    public static String TIME = ":00";


    public static String new_orderNo(String machindId) {
        DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmss");
        String orderNo = "DD" + dateFormat.format(new Date()) + RandomGUIDUtil.getRandom() + RandomGUIDUtil.getLastNum();

        return orderNo;
    }

    public static String new_orderNo1() {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        return dateFormat.format(new Date());
    }

    public static String new_orderNo(String orderNo, String SSS) {
        return "DD" + orderNo + SSS + RandomGUIDUtil.getLastNum();
    }

    public static String date(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.format(date);
    }

    public static String date2(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        return dateFormat.format(date);
    }

    public static String date3(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("HH时mm分ss秒");
        return dateFormat.format(date);
    }

    public static String date4(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("MM-dd");
        return dateFormat.format(date);
    }

    public static String date5(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("MM-dd HH:mm");
        return dateFormat.format(date);
    }

    public static String time(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.format(date);
    }

    public static String time(Date date, String format) {
        DateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }

    public static String time2(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm");
        return date != null ? dateFormat.format(date) : "";
    }

    public static String time3(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        return dateFormat.format(date);
    }

    public static String time4(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("yyMMddHHmmss");
        return dateFormat.format(date);
    }

    public static String time5(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        return dateFormat.format(date);
    }

    public static String fileno() {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return dateFormat.format(new Date());
    }

    public static String timelog() {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");
        return dateFormat.format(new Date());
    }

    public static Date parsetime(String timeStr) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.parse(timeStr);
    }

    public static Date parsetime(String timeStr, String format) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.parse(timeStr);
    }

    public static Date parsetime1(String datestr) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd-HH:mm:ss");
        return dateFormat.parse(datestr);
    }

    public static Date parsetime3(String timeStr) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        return dateFormat.parse(timeStr);
    }

    public static Date parsetime_start(String timeStr) {
        try {
            DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            return dateFormat.parse(timeStr + START);
        } catch (Exception e) {
            // TODO: handle exception
            return null;
        }
    }

    public static Date parsetime_end(String timeStr) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.parse(timeStr + END);
    }

    public static Date parseDateByDefaultFormat(String timeStr) throws ParseException {
        if (StringUtils.isEmpty(timeStr)) return null;
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        return dateFormat.parse(timeStr);
    }

    public static Date parsetime_hour(String timeStr) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return dateFormat.parse(timeStr + TIME);
    }

    public static String wx_time(String timeStr) throws ParseException {
        DateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
        return time(dateFormat.parse(timeStr));
    }

    public static String date2str(Date time) {
        return time != null ? String.valueOf(time.getTime()) : "";
    }

    public static Date str2date(String timeStr) {
        if (StringUtils.notNull(timeStr)) {
            Date date = new Date();
            date.setTime(Long.valueOf(timeStr).longValue());
            return date;
        }
        return null;
    }

    public static String subdays(Date pDate, Date nDate) {
        long p = pDate.getTime();
        long n = nDate.getTime();
        String sub = String.valueOf((n - p) / 1000L / 60L / 60L / 24L);

        return sub.length() == 1 ? "0" + sub : sub;
    }

    public static String subhours(Date pDate, Date nDate) {
        long p = pDate.getTime();
        long n = nDate.getTime();
        String sub = String.valueOf((n - p) / 1000L / 60L / 60L % 24L);

        return sub.length() == 1 ? "0" + sub : sub;
    }

    public static String subminutes(Date pDate, Date nDate) {
        long p = pDate.getTime();
        long n = nDate.getTime();
        String sub = String.valueOf((n - p) / 1000L / 60L % 60L);

        return sub.length() == 1 ? "0" + sub : sub;
    }

    public static String startTime(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd" + START);
        return dateFormat.format(date);
    }

    public static String endTime(Date date) {
        DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd" + END);
        return dateFormat.format(date);
    }

    public static String startPayTime(Date payTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(payTime);
        calendar.add(12, -30);

        return time(calendar.getTime());
    }

    public static String endPayTime(Date payTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(payTime);
        calendar.add(12, 30);

        return time(calendar.getTime());
    }

    public static String startPayTime2(Date updateTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(updateTime);
        calendar.add(12, -2);

        return time(calendar.getTime());
    }

    public static String endPayTime2(Date updateTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(updateTime);
        calendar.add(12, 1);

        return time(calendar.getTime());
    }

    public static String startMonth(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.add(6, -30);

        return startTime(calendar.getTime());
    }

    public static String startWeek(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.add(6, -7);

        return startTime(calendar.getTime());
    }

    public static Date subTime(Date time, int sub) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.add(6, sub);

        return calendar.getTime();
    }

    public static String add1s(String timeStr) {
        Calendar calendar = Calendar.getInstance();
        try {
            calendar.setTime(parsetime3(timeStr));
            calendar.add(13, 1);

            return time3(calendar.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return time3(new Date());
    }

    public static String expireTime(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.add(12, 30);

        return time3(calendar.getTime());
    }

    public static Date onlineTime(Date updateTime) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(updateTime);
        calendar.add(12, -5);

        return calendar.getTime();
    }

    public static Date month_one() {
        Calendar calendar = Calendar.getInstance();
        calendar.set(5, 1);
        calendar.set(11, 0);
        calendar.set(12, 0);
        calendar.set(13, 0);
        return calendar.getTime();
    }

    public static String datesub(String time) {
        return time.substring(0, time.indexOf(" "));
    }

    public static String timesub(String time) {
        return time.substring(0, time.lastIndexOf(":"));
    }

    public static String parsetime2(String timeStr) {
        return timeStr + TIME;
    }

    public static boolean afterDate(String timeStr) {
        boolean afterDate = true;
        try {
            Date time = parsetime(timeStr);

            afterDate = time.after(new Date());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return afterDate;
    }

    public static String return_time(String shijian) {
        int year = Integer.valueOf(shijian.substring(0, 2), 16).intValue();
        int month = Integer.valueOf(shijian.substring(2, 4), 16).intValue();
        int day = Integer.valueOf(shijian.substring(4, 6), 16).intValue();
        int hour = Integer.valueOf(shijian.substring(6, 8), 16).intValue();
        int minute = Integer.valueOf(shijian.substring(8, 10), 16).intValue();
        int second = Integer.valueOf(shijian.substring(10, 12), 16).intValue();

        System.out.println(year);
        System.out.println(month);
        System.out.println(day);
        System.out.println(hour);
        System.out.println(minute);
        System.out.println(second);

        return shijian;
    }

    public static String getTimeByMinute(int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, minute);
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(calendar.getTime());
    }


    public static Date str2Date(String time, String format) throws ParseException {
        if (null == format) format = "yyyy-MM-dd HH:mm:ss";
        DateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.parse(time);
    }

    public static Date addOneDay(Date input) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(input);
        calendar.add(Calendar.DAY_OF_MONTH, 1);
        return calendar.getTime();
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     *
     * @param start
     * @param end
     * @return
     */
    public static int differentDaysByMillisecond(Date start, Date end) {
        int days = (int) ((end.getTime() - start.getTime()) / (1000 * 3600 * 24));
        return days;
    }

    /**
     * 获取当天0点的日期
     *
     * @param date
     * @return
     */
    public static Date getZeroDate(Date date) throws ParseException {
        return parseDateByDefaultFormat(date(date));
    }


    /**
     * 取得指定日期过 day 天后的日期 (当 day 为负数表示指定日之前);
     *
     * @param date null 表示当天
     * @param day
     * @return
     */
    public static Date nextDay(Date date, int day) {
        Calendar cal = Calendar.getInstance();
        if (date != null) {
            cal.setTime(date);
        }
        cal.add(Calendar.DAY_OF_YEAR, day);
        return cal.getTime();
    }

    public static Date getNow(String format) throws ParseException {
        Date dt = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.parse(dateFormat.format(dt));
    }

    /**
     * 通过年份 和 第几周 获取日期 （该周的第一天和下周的第一天）
     *
     * @param year
     * @param week 从1开始
     * @return
     */
    public static List<Date> getDatesByYearAndWeek(int year, int week) {
        List<Date> res = new ArrayList<>();
        WeekFields weekFields = WeekFields.of(Locale.getDefault());
        LocalDate ld1 = LocalDate.now()
                .withYear(year)
                .with(weekFields.weekOfYear(), week)
                .with(weekFields.dayOfWeek(), 1);

        LocalDate ld2 = LocalDate.now()
                .withYear(year)
                .with(weekFields.weekOfYear(), week + 1)
                .with(weekFields.dayOfWeek(), 1);

        Date dateStart = Date.from(ld1.atStartOfDay(ZoneId.systemDefault()).toInstant());
        Date dateEnd = Date.from(ld2.atStartOfDay(ZoneId.systemDefault()).toInstant());

        res.add(dateStart);
        res.add(dateEnd);


        return res;
    }

    /**
     * 通过年份 和 第几月 获取日期 （该月的第一天和下月的第一天）
     *
     * @param year
     * @param month 从1开始
     * @return
     */
    public static List<Date> getDatesByYearAndMonth(int year, int month) {
        List<Date> res = new ArrayList<>();
        LocalDate ld1 = LocalDate.now().withYear(year).withMonth(month).withDayOfMonth(1);
        LocalDate ld2 = LocalDate.now().withYear(year).withMonth(month + 1).withDayOfMonth(1);

        Date dateStart = Date.from(ld1.atStartOfDay(ZoneId.systemDefault()).toInstant());
        Date dateEnd = Date.from(ld2.atStartOfDay(ZoneId.systemDefault()).toInstant());

        res.add(dateStart);
        res.add(dateEnd);


        return res;
    }

    /**
     * 根据开始日期和结束日期 获取日期描述
     *
     * @param start
     * @param end
     * @return （10.01至10.09）
     */
    public static String getDescFromDates(Date start, Date end) {
        DateFormat dateFormat = new SimpleDateFormat("MM.dd");
        String strStart = dateFormat.format(start);
        String strEnd = dateFormat.format(end);
        return String.format("(%s至%s)", strStart, strEnd);
    }

    /**
     * 获取intervalDays天前日期
     *
     * @param intervalDays 多少天前
     * @return 调整后的日期
     * @Param startDate 计算起始日期
     */
    public static Date dateSub(Date startDate, int intervalDays) {
        Date dat = null;
        Calendar cd = Calendar.getInstance();
        cd.setTime(startDate);
        cd.add(Calendar.DATE, intervalDays);
        dat = cd.getTime();
        return dat;
    }

    /**
     * 获取某天0点
     */
    public static Date getStartTimeofDay(Date date) {
        Date dat = null;
        Calendar cd = Calendar.getInstance();
        cd.setTime(date);
        cd.set(Calendar.HOUR_OF_DAY, 0);
        cd.set(Calendar.MINUTE, 0);
        cd.set(Calendar.SECOND, 0);
        cd.set(Calendar.MILLISECOND, 0);
        dat = cd.getTime();
        return dat;
    }


    /**
     * 获取最大值
     *
     * @param date1
     * @param date2
     * @return
     */
    public static Date max(Date date1, Date date2) {
        if (date1 == null) {
            return date2;
        }
        if (date2 == null) {
            return null;
        }
        return date1.before(date2) ? date2 : date1;
    }


    /**
     * 获取两个日期相差分钟数
     * @param begin
     * @param end
     * @return
     */
    public static double getMinutesBetweenDates(Date begin, Date end,Date minDate,Date maxDate) {
        if (begin == null || begin.before(minDate)){
            begin = minDate;
        }
        if (end == null || end.after(maxDate)){
            end = maxDate;
        }

        long between = (end.getTime() - begin.getTime()) / 1000;//除以1000是为了转换成秒
        double minutes = between * 1.0 / 60;
        return minutes;
    }

    /**
     * 获取当月的第一天和下月的第一天
     * @return
     */
    public static List<Date> getMonthStartAndEnd() throws ParseException {
        Calendar  calendar1=Calendar.getInstance();//获取当前日期
        calendar1.add(Calendar.MONTH, 0);
        calendar1.set(Calendar.DAY_OF_MONTH,1);

        //获取前月的最后一天
        Calendar calendar2 = Calendar.getInstance();
        calendar2.add(Calendar.MONTH, 1);
        calendar2.set(Calendar.DAY_OF_MONTH,1);


        return Arrays.asList(getZeroDate( calendar1.getTime()),getZeroDate(calendar2.getTime()));
    }


    /**
     * 时间戳转Date
     * @param timestamp 时间戳 秒
     * @return
     */
    public static Date longToDate(Long timestamp) {
        return new Date(timestamp);
    }

    /**
     * 时间戳转字符串时间
     * @param timestamp 时间戳 秒
     * @param format format格式
     * @return
     */
    public static String longToDateString(Long timestamp, String format) {
        SimpleDateFormat sdf =  new SimpleDateFormat(format);
        Date date = new Date(timestamp * 1000);
        return sdf.format(date);
    }
}
